﻿using System;

namespace PMS.Core
{
    public abstract class EntityBase<IdT>
    {
        public virtual IdT Id { get; protected set; }

        #region --- override methods ---

        public override bool Equals(object obj)
        {
            return Equals(obj as EntityBase<IdT>);
        }

        public override int GetHashCode()
        {
            return Equals(Id, default(IdT)) ? base.GetHashCode() : Id.GetHashCode();
        }

        #endregion --- override methods ---

        #region --- public methods ---

        public virtual bool Equals(EntityBase<IdT> other)
        {
            if (other == null) return false;
            if (ReferenceEquals(this, other)) return true;
            if (!IsTransient(this) && !IsTransient(other) && Equals(Id, other.Id))
            {
                var otherType = other.GetTypeUnProxy();
                var thisType = this.GetTypeUnProxy();
                return thisType.IsAssignableFrom(otherType) || otherType.IsAssignableFrom(thisType);
            }
            return false;
        }

        #endregion --- public methods ---

        #region --- private methods ---

        private static bool IsTransient(EntityBase<IdT> obj)
        {
            return (obj != null && Equals(obj.Id, default(IdT)));
        }

        private Type GetTypeUnProxy()
        {
            return GetType();
        }

        #endregion --- private methods ---
    }

    public abstract class EntityBase : EntityBase<Guid> { }
}